package plantshop.tests;
import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import plantshop.model.Characteristics;
import plantshop.model.exceptions.ImproperLengthException;


public class CharacteristicsTest {
	Characteristics testNormal,testSingle,testEmpty,testNegative,testZero;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	@Before
	public void setUp() throws Exception {
		testNormal = new Characteristics(2,6,3,1,5);
		testSingle = new Characteristics(3);
		testEmpty = new Characteristics();
		testNegative = new Characteristics(3,7,-2,4);
		testZero = new Characteristics(0);
	}

	@After
	public void tearDown() throws Exception {
		testNormal = null;
		testSingle = null;
		testEmpty = null;
		testNegative = null;
		testZero = null;
	}
	
	@Test
	public void testEquals(){
		assertTrue(testNormal.equals(testNormal));
		assertTrue(testNormal.equals(new Characteristics(2,6,3,1,5)));
		assertFalse(testNormal.equals(testZero));
	}

	@Test
	public void testGetClosenessIntArray() {
		int[] arrayBeingCompared = new int[]{3,2,1,4,7};
		int[] arrayBeingCompared1 = new int[]{3,2,1,4,7,2,8,10,5,3};
		try{
			assertEquals(testNormal.getCloseness(arrayBeingCompared),34,0.1);
			assertEquals(testZero.getCloseness(3),9,0.1);
			assertEquals(testNegative.getCloseness(4,6,0,4),6,0.1);
			assertEquals(testSingle.getCloseness(5),4,0.1);
		}
		catch(ImproperLengthException e){
			fail("Improper Exception Handling");
		}
		try {
			assertEquals(testNormal.getCloseness(arrayBeingCompared1),34,0.1);
		} catch (ImproperLengthException e) {
			//Execution should come through this block
			assertTrue(true);
		}
		
		try {
			assertEquals(testSingle.getCloseness(arrayBeingCompared),0,0.1);
		} catch (ImproperLengthException e) {
			assertTrue(true);
		}
		
		try {
			assertEquals(testEmpty.getCloseness(arrayBeingCompared),0,0.1);
		} catch (ImproperLengthException e) {
			assertTrue(true);
		}
		
		try {
			assertEquals(testNegative.getCloseness(arrayBeingCompared),34,0.1);
		} catch (ImproperLengthException e) {
			assertTrue(true);
		}
		
		try {
			assertEquals(testZero.getCloseness(arrayBeingCompared),9,0.1);
		} catch (ImproperLengthException e) {
			assertTrue(true);
		}
	}

	@Test
	public void testGetClosenessCharacteristics() {
		Characteristics compare = new Characteristics(4,3,2,1);
		try {
			assertEquals(testNormal.getCloseness(compare),14,0.1);
		} catch (ImproperLengthException e) {
			assertTrue(true);
		}
	}

	@Test
	public void testGetDominant() {
		assertEquals(testNormal.getDominant(),1);
		assertEquals(testSingle.getDominant(),0);
		assertEquals(testEmpty.getDominant(),-1);
		assertEquals(testNegative.getDominant(),1);
		assertEquals(testZero.getDominant(),-1);
		
		//Dominant threshold = 1
		Characteristics testHas = new Characteristics(2,1,3,0,7,2);
		Characteristics testNot = new Characteristics(1,1,1,1,1,1);
		assertEquals(4,testHas.getDominant());
		assertEquals(-1,testNot.getDominant());
		
	}
	
	@Test
	public void testGetChars()
	{
		assertTrue(Arrays.equals(new int[]{2,6,3,1,5}, testNormal.getChars()));
		assertTrue(Arrays.equals(new int[]{3}, testSingle.getChars()));
		assertTrue(Arrays.equals(new int[]{}, testEmpty.getChars()));
		assertTrue(Arrays.equals(new int[]{3,7,-2,4}, testNegative.getChars()));
		assertTrue(Arrays.equals(new int[]{0}, testZero.getChars()));
	}
	
	@Test
	public void testToString()
	{
		assertEquals(Arrays.toString(new int[]{2,6,3,1,5}), testNormal.toString());
		assertEquals(Arrays.toString(new int[]{3}), testSingle.toString());
		assertEquals(Arrays.toString(new int[]{}), testEmpty.toString());
		assertEquals(Arrays.toString(new int[]{3, 7, -2, 4}), testNegative.toString());
		assertEquals(Arrays.toString(new int[]{0}), testZero.toString());
	}
}